package benchmarks.tpch.mongo.queries;

import api.Configuration;
import api.connection.ConnectionMongo;
import api.connection.DBConnection;
import api.result.Result;
import com.mongodb.*;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.BsonDocument;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.Date;

public class Q1Mongo extends GenericQueryMongo {
    public static final String queryName = "Q1";

    public Q1Mongo(){
        super.queryName = queryName;
    }

    private static String matchStringQuery = "{ $match : { \"shipdate\" : { $lte: new Date(1998, 8, 1) }} }";

    private static String groupStringQuery = "{ $group : { " +
            "_id : { \"returnflag\" :\"$returnflag\", \"linestatus\" : \"$linestatus\"}, " +
            "sum_qty : { $sum : \"$quantity\"},\n" +
            "sum_base_price : { $sum : \"$extendedprice\"}, " +
            "sum_disc_price : { $sum : { $multiply : [ \"$extendedprice\", " +
            "{ $subtract : [1, \"$discount\"]}] }}, sum_charge : { $sum : {$multiply : [ \"$extendedprice\", " +
            "{ $subtract : [1, \"$discount\"]}, {$add : [1, \"$tax\"]}] }}, avg_qty : { $avg : \"$quantity\"}, " +
            "avg_price : { $avg : \"$extendedprice\"}, avg_disc : { $avg : \"$discount\"}, count_order : { $sum : 1} " +
            "} }";

    private static String sortStringQuery = "{ $sort : {\"_id.returnflag\" : 1, \"_id.linestatus\" : 1}}";

    public Result run(DBConnection dbConnection) {
        ConnectionMongo connectionMongo = (ConnectionMongo)dbConnection;
        MongoClient mongoClient = connectionMongo.makeConnection();
        MongoDatabase database = mongoClient.getDatabase("tpch");
        BsonDocument matchBsonQuery = BsonDocument.parse(matchStringQuery);
        BsonDocument groupBsonQuery = BsonDocument.parse(groupStringQuery);
        BsonDocument sortBsonQuery = BsonDocument.parse(sortStringQuery);
        ArrayList<Bson> aggregateQuery = new ArrayList<>();
        aggregateQuery.add(matchBsonQuery);
        aggregateQuery.add(groupBsonQuery);
        aggregateQuery.add(sortBsonQuery);
        AggregateIterable<Document> result  = database.getCollection("deals").aggregate(aggregateQuery);
        MongoCursor<Document> iterator = result.iterator();
        ArrayList<Document> results = new ArrayList<>();
        while (iterator.hasNext()) {
            results.add(iterator.next());
        }
//        System.out.println("Q1 ok");
        return null;
    }

//    public Result run(DBConnection dbConnection){
//        int delta = 80;String collectionName = "deals";
//        ConnectionMongo connectionMongo =(ConnectionMongo)dbConnection;
//        MongoClient mongoClient = connectionMongo.makeConnection();
//        MongoDatabase database = mongoClient.getDatabase("tpch");
//        DB db = mongoClient.getDB("tpch");
//        for (String name : database.listCollectionNames()) {
//            System.out.println(name);
//        }
//        DBCollection collection = db.getCollection(collectionName);
//        System.out.println(collection.findOne().toString());
//        BasicDBObject key = new BasicDBObject();
//        key.put("returnflag", true);
//        key.put("linestatus", true);
//
//        String reduce = "function (doc, out){"
//                +"out.count_order++;"
//                +"out.sum_qty += doc.quantity;"
//                +"out.sum_base_price += doc.extendedprice;"
//                +"out.sum_disc_price += doc.extendedprice * (1 - doc.discount);"
//                +"out.sum_charge += doc.extendedprice * (1 - doc.discount) * (1 + doc.tax);"
//                +"out.avg_disc += doc.discount"
//                +"};";
//
//        String finalize = "function (out) {"
//                +"out.avg_qty = out.sum_qty / out.count_order;"
//                +"out.avg_price = out.sum_base_price / out.count_order;"
//                +"out.avg_disc = out.avg_disc / out.count_order"
//                +"};";
//
//        BasicDBObject cond = new BasicDBObject();
//        Date date = new Date(98, 11, 1);
//        long t = date.getTime();
//        t -= delta * 24 * 3600 * 1000;
//        Date date2 = new Date(t);
//        cond.append("shipdate", new BasicDBObject("$lte", date2));
//
//        BasicDBObject initial = new BasicDBObject();
//        initial.append("count_order", 0).append("sum_qty", 0).append("sum_base_price", 0)
//                .append("sum_disc_price", 0).append("sum_charge", 0).append("avg_disc", 0);
//
//        BasicDBList groupList = (BasicDBList)db.getCollection(collectionName).group(key, cond, initial, reduce, finalize);
//       /* System.out.println("Successfully group " + groupList.size());
//        if(groupList != null && groupList.size() > 0){
//            for( int i = 0; i < groupList.size(); i++){
//                BasicDBObject format = (BasicDBObject)groupList.get(i);
//                System.out.println("The answer is: " + format.toString());
//            }
//        }
//        else{
//            System.out.println("none");
//        }*/
//        return null;
//    }

    private static class TestQ1{
        public static void main(String[] args){
            Configuration config = new Configuration();
            config.setBenchmark("tpch");
            config.setDb_username("root");
            config.setDb_password("123456");
            Q1Mongo q1Mongo = new Q1Mongo();
            DBConnection dbConnection =new ConnectionMongo(config);
            q1Mongo.run(dbConnection);
        }
    }
}